2oneweek.dev

19. Function Instance (feat. new)

    Tags

  • JavaScript
19. Function Instance (feat. new) thumbnail

Function Instance

Function 의 구분

  1. built-in Function Object - 엔진 제공
  2. Function 키워드로 생성하는 Function Object
  3. new 연산자로 생성하는 Function Instance

Function Object라 말하고 있지만, Function Object도 결국 Instance다. built-in Function Object로 생성하기 때문이다. 성격적으로는 인스턴스지만, new 연산자로 생성한 인스턴스와 차이가 있기 때문에, 앞에서는 Function Object로 말했다.

new Function

  • new 연산자로 생성하는 Function Instance는 prototype에 프로퍼티를 작성한다.
function Book(point) { this.point = point; } Book.prototype.getPoint = function () { return this.point + 200; }; var obj = new Book(100); console.log(obj.point); console.log(obj.getPoint);
  1. 엔진은 Book이라는 function object를 만든다. 이때 book Object의 prototype이 만들어진다.(엔진이 자동으로 만들어줌)

    • prototype 또한 Object다.
  2. Book.prototype.getPoint = function(){}

    • prototype 또한 Object이기 때문에 위와 같이 프로퍼티를 연결할 수 있다.
    • Book.prototype에 getPoint 프로퍼티를 만들고, function Object를 할당한다.
  3. new Book실행

    • Book의 인스턴스를 생성하고, 생성한 인스턴스를 실행해서 point를 할당하게 된다.
    • 이때 내부의 this는 인스턴스를 참조하게 된다.
    • Book.prototype에 연결된 프로퍼티를 생성한 인스턴스에 연결한다.
    • 그리고 이러한 인스턴스를 return 하게 된다.


용어 정리

  1. 생성자 함수

    • new book()에서 book()이 생성자 함수다. new 연산자와 함께 인스턴스를 생성하는 함수를 "생성자 함수"라고 한다.
    • 생성자 함수는 인스턴스를 생성하고 반환한다.
    • 인스턴스에 초기값을 설정해준다.
  2. new 연산자

    • 인스턴스 생성을 제어한다.(new 자체가 인스턴스를 생성하는 것이 아니다.)
    • "생성자 함수를 호출"하고 생성자 함수가 인스턴스를 반환해준다.


생성자 함수 실행과정

function Book(point) { this.point = point; } Book.prototype.getPoint = function () { return this.point + 200; }; var obj = new Book(100);
  1. 엔진이 function Book()의 function 키워드를 만나면서 function Object 생성한다.

    • 이때, 엔진은 [[Construct]]에 Book() 함수 전체를 참조할 수 있도록 참조를 해놨다.
  2. 엔진이 new Book(100)을 만난다.

    • 엔진은 new키워드를 만나면 function Object의 내부 프로퍼티 [[Construct]]를 호출하게 되고(결국 함수 그 자체???를 호출), 파라미터 값으로 100을 넘겨준다.
  3. [[Construct]]가 호출되면, 인스턴스를 생성해서 반환한다.

  4. 반환된 인스턴스를 new 연산자가 받게된다. 그리고 new 연산자는 obj에 인스턴스를 할당한다.



"Instance" 생성 과정

function Book(point) { this.point = point; } Book.prototype.getPoint = function () { return this.point + 200; }; var obj = new Book(100);
  1. new Book(100)을 실행하면, 엔진은 Book Function Object의 [[Construct]]를 호출하고 파라미터 값을 [[Construct]]에 넘겨준다.
  2. [[Construct]]는 우선 빈 오브젝트를 생성하고 채워나가기 시작한다.
    • 이 빈 오브젝트가 인스턴스다.
  3. 엔진은 이 빈 오브젝트에 내부 처리용 프로퍼티를 설정해 나간다.
    • 공통 프로퍼티 설정
    • 선택적 프로퍼티 - 함수에 필요한 내부 프로퍼티를 설정
    • [[Class]] 프로퍼티에 "Object"를 설정하는데, 따라서 생성한 인스턴스 타입은 Object가 된다.
    • [[Prototype]]에는 Book.prototype에 연결된 프로퍼티(메소드)를 설정한다.즉 인스턴스에서 프로토타입에 연결된 메서드들을 가지게 된다.
    • 이때 인스턴스 __proto__constructor도 같이 설정한다.(function object)(생성자)함수 자체를 참조하게 된다.

위의 과정의 결과

"Book인스턴스" : { point = 100, __proto__ = { constructor : Book, getPoint : function(){}, __proto__ : Object } }

"function object"의 constructor

"Book_Function_Object" : { prototype : { constructor : Book } }
  • constructor 프로퍼티는 생성하는 function Object를 참조한다.
    • 이것은 function Object를 생성할 때 설정된다.(엔진이 해줌)
  • constructor 프로퍼티는 prototype에 연결되어 있다.
    • constructor 프로퍼티의 값은 Book function Object 전체를 참조한다.
  • ES5 기준에서는 constructor변경이 불가능하여 생성자를 활용할 수 없었지만, ES6부터는 constructor 변경이 가능해졌다. (생성자 함수에 코드를 추가할 수 있게 되었다. 역시 ES6를 사용해야만 가능하다)


function object의 constructor에 대해서

// Function Object이자 생성자 함수다 var Book = function(){} var obj = new Book(); // function object의 constructor와 Book함수 자체를 비교 console.log(Book === Book.prototype.constructor) //=> true // 인스턴스의 __proto__.constructor와 Book함수 자체를 비교 console.log(Book == obj.constructor) //=> true console.log(typeof Book) //=> function console.log(typeof obj) //=> object
  1. console.log(Book === Book.prototype.constructor) //=> true

    • Book Object와 Book.prototype.constructor가 타입까지 같다는 뜻
    • Book (function)Object를 생성할 때, Book.prototype.constructor가 Book Object를 참조하기 때문이다.
  2. console.log(Book == obj.constructor) //=> true

    • obj(인스턴스)의 constructor가 Book (function)Object를 참조한다.
  3. typeof Book & typeof obj

    • 오브젝트의 타입이 바뀐다는 것은, 오브젝트 성격과 목적이 바뀐 것을 뜻한다. 따라서 다른 관점에서 접근해야 한다.
    • new 를 통해 function에서 object로 바뀌었다.(사실 function도 js에선 object의 하위 레벨이다) object로 바뀌었다는 것은 "인스턴스"임을 의미한다. 인스턴스의 가장 큰 특징은 프로토타입을 가지며, 이 프로토타입에는 많은 메소드들이 연결된다는 것이다. 즉, 함수가 하나가 아니라 다수가 되었다. 이게 함수와 인스턴스의 차이다.


함수와 인스턴스의 차이

사실 자바스크립트에서 built-in Function은 built-in Object의 하위 개념으로 분류하고 있다. typeof 연산자가 object를 반환하는 것은 인스턴스이며 function을 반환하는 것은 함수라고 보면 된다.

인스턴스의 가장 큰 특징은, 프로토타입이 있으며 프로토타입에는 여러가지 메소드가 연결될 수 있다는 것이다. new 키워드를 사용하여 function으로 인스턴스를 만들 수 있는데, 하나의 함수로 만든 인스턴스임에도 불구하고, 여러개의 함수(메소드라 부르는 것이 더 타당함)가 존재할 수 있다는 것이다.



prototype Object

JS내의 모든 객체는, 자신의 상위 객체와 연결되어 있다. 이러한 상위 객체를 Prototype Object 또는 줄여서 prototype이라고 한다.

prototype의 목적

  1. 프로퍼티 공유 prototype 객체는 생성자 함수에 의해 생성된 각각의 객체에 공유 프로퍼티를 제공해 줄 수 있다. (생성한 인스턴스에서 원본 prototype의 프로퍼티를 공유할 수 있다.)

    • var obj = new Book(1234)로 인스턴스를 생성하고, obj.getPoint()를 하게 되면, 인스턴스의 getPoint를 호출하는 것이 아니라, Book.prototype.getPoint를 호출하게 된다.
    • obj 인스턴스 내에는 Book.prototype에 접근할 수 있는 경로가 저장되어 prototype의 메소드 호출이 가능하다.
    • 이것 말고, 공유에는 다른 기능??이 있다 나중에 살펴보자
  2. prototype 확장 prototype 객체에 프로퍼티를 추가하여 prototype을 확장할 수 있다.

    • Book.prototype.getPoint = function(){} 처럼 prototype을 확장 할 수 있다.
  3. Instance 상속 function 인스턴스를 연결하여 상속을 구현한다.

    • Point.prototype = new Book() 자바스크립트의 상속은 프로토타입 확장의 개념이라고 보면 된다.


Written by@2-one-week
현재 블로그 개발 중

GitHubLinkedIn